using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Collections;
using System.Collections.Specialized;
using Gratamira.AccesoDato;

namespace Gratamira.CapaNegocio
{
    public class Reserva
    {
        StringCollection mSql = new StringCollection();
        #region propiedades
        private string _ReservaID="";
        private DateTime _Fecha;
        private char _Estado;
        private Int32 _TerceroID;
        private string _NombreTercero;
        private string _Referencia;
        private string _Observacion;
        private string _CodUsuCre;
        private DateTime _FecHorCre;
        private string _UsuUltMod;
        private DateTime _FecUltMod;

        public string ReservaID
        {
            get { return _ReservaID; }
            set { _ReservaID = value; }
        }
        public char Estado
        {
            get { return _Estado; }
            set { _Estado = value; }
        }
        public DateTime Fecha
        {
            get { return _Fecha; }
            set { _Fecha = value; }
        }
        public Int32 TerceroID
        {
            get { return _TerceroID; }
            set { _TerceroID = value; }
        }
        public string NombreTercero
        {
            get { return _NombreTercero; }
            set { _NombreTercero = value; }
        }
        public string Referencia
        {
            get { return _Referencia; }
            set { _Referencia = value; }
        }
        public string Observacion
        {
            get { return _Observacion; }
            set { _Observacion = value; }
        }
        public string CodUsuCre
        {
            get { return _CodUsuCre; }
            set { _CodUsuCre = value; }
        }
        public DateTime FecHorCre
        {
            get { return _FecHorCre; }
            set { _FecHorCre = value; }
        }
        public string UsuUltMod
        {
            get { return _UsuUltMod; }
            set { _UsuUltMod = value; }
        }
        public DateTime FecUltMod
        {
            get { return _FecUltMod; }
            set { _FecUltMod = value; }
        }
        #endregion Propiedades

        #region Constructores
        public Reserva()
        {  }
        public Reserva(DataSet dsDatos, string pReservaID)
        {
            //Constructor para Edicion de Maestra y Detalle del Movimiento
            ReservaID = pReservaID;
            string strSql = "SELECT R.*, T.Nombre NombreTercero FROM RESERVA R " +
                            " JOIN Tercero T ON R.TerceroID = T.TerceroID " +
                            " WHERE ReservaID = '" + ReservaID + "'";
            DataTable dt = new DataTable();
            accesoDatos p = new accesoDatos();
            dt = p.leerDatosSQL(strSql, "");
            dt.TableName = "Reserva";
            dsDatos.Tables.Add(dt);
            //Llenar el Dataset con los datos del detalle de este registro
            string tSql = "SELECT D.ProductoID, P.Nombre, D.Reservado,D.Utilizado, D.Saldo, P.UnidadManejoID Unidad, P.Estado " +
                          " FROM DETRES D JOIN Producto P ON D.ProductoID = P.ProductoID " +
                          " WHERE D.ReservaID = '" + ReservaID + "'" +
                          " ORDER BY D.ProductoID";
            DataTable dtTabla = new DataTable();
            dtTabla = p.leerDatosSQL(tSql,"");
            dtTabla.TableName = "DetRes";
            ////Crear restriccion de no repetir producto en el detalle
            DataColumn col = new DataColumn();
            col = dtTabla.Columns["ProductoID"];
            UniqueConstraint restriccion = new UniqueConstraint("RefUnica",col);
            dtTabla.Constraints.Add(restriccion);
            dsDatos.Tables.Add(dtTabla);
        }
        #endregion Constructores

        #region Metodos publicos
        public bool actualizarReserva(DataSet dsDatos)
        {
            //Actualizar registro encabezado
            asignarRegistro(dsDatos);
            actualizarRegistro(dsDatos);
            //Enviar comandos SQL en una transaccion
            accesoDatos p = new accesoDatos();
            p.ejecutarLoteSQL(mSql);
            dsDatos.AcceptChanges();
            return true;
        }
        public bool anularReserva(DataSet dsDatos)
        {
            //Modifica el estado de la reserva
            mSql.Clear();
            //Actualiza el registro de reserva
            mSql.Add("UPDATE RESERVA SET " +
                    " Estado = 'A' " +
                    ",UsuaAnul = '" + UsuUltMod + "'" +
                    ",FechAnul = '" + FecUltMod.ToString("MM/dd/yyyy HH:mm:ss") + "' " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            //Asigna Saldo = Reservado en todos los registros del detalle 
            mSql.Add("UPDATE DETRES SET " +
                    " Saldo = 0 " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            accesoDatos p = new accesoDatos();
            p.ejecutarLoteSQL(mSql);
            dsDatos.AcceptChanges();
            return true;
        }
        public bool confirmarReserva(DataSet dsDatos)
        {
            //Modifica el estado de la reserva
            mSql.Clear();
            //Actualiza el registro de reserva
            mSql.Add("UPDATE RESERVA SET " +
                    " Estado = 'C' " + 
                    ",UsuaConf = '" + UsuUltMod + "'" +
                    ",FechConf = '" + FecUltMod.ToString("MM/dd/yyyy HH:mm:ss") + "' " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            //Asigna Saldo = Reservado en todos los registros del detalle 
            mSql.Add("UPDATE DETRES SET " +
                    " Saldo = Reservado " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            accesoDatos p = new accesoDatos();
            p.ejecutarLoteSQL(mSql);
            dsDatos.AcceptChanges();
            return true;
        }
        public bool teminarReserva(DataSet dsDatos)
        {
            //Modifica el estado de la reserva
            mSql.Clear();
            //Actualiza el registro de reserva
            mSql.Add("UPDATE RESERVA SET " +
                    " Estado = 'T' " +
                    ",UsuaAnul = '" + UsuUltMod + "'" +
                    ",FechAnul = '" + FecUltMod.ToString("MM/dd/yyyy HH:mm:ss") + "' " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            //Asigna Saldo = Reservado en todos los registros del detalle 
            mSql.Add("UPDATE DETRES SET " +
                    " Saldo = 0 " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            accesoDatos p = new accesoDatos();
            p.ejecutarLoteSQL(mSql);
            dsDatos.AcceptChanges();
            return true;
        }

        public bool insertarReserva(DataSet dsDatos)
        {
            //Iniciar vbles de auditoria
            CodUsuCre = UsuUltMod;
            FecHorCre = FecUltMod;
            //Instanciar el string SQL que se enviara a la Base de datos
            mSql.Clear();
            //Insertar nueva Reserva
            asignarRegistro(dsDatos);
            //Generar consecutivo de la reserva por Empresa
            //ReservaID = Convert.ToString(leerConsecReserva() + 1);
            //dsDatos.Tables["Reserva"].Rows[0]["ReservaID"] = ReservaID;
            //Crear cadenas de datos del registro a insertar
            insertarRegistro(dsDatos);
            //Enviar comandos SQL en una transaccion
            accesoDatos p = new accesoDatos();
            p.ejecutarLoteSQL(mSql);
            dsDatos.AcceptChanges();
            return true;
        }
        public void leerReservas(string pReservaID, string pNTercero, DateTime pFechaInicial, DateTime pFechaFinal, char pEstado, DataSet dsDatos)
        {
            //Llamado desde la consulta de Reservas
            //Crea el filtro para las consultas
            string tFiltro = "";
            if (!String.IsNullOrEmpty(pReservaID))
            {
                tFiltro += " R.ReservaID LIKE '%" + pReservaID + "%' AND ";
            }
            if (!String.IsNullOrEmpty(pNTercero))
            {
                tFiltro += " T.Nombre LIKE '%" + pNTercero + "%' AND ";
            }
            //Verificar si se filtra por estado
            if (pEstado != 'O')
            {
                tFiltro += " R.Estado = '" + pEstado + "' AND "; 
            }

            tFiltro += " R.fecha BETWEEN '" + pFechaInicial.Date.ToString("yyyy/MM/dd") + "' AND '" + pFechaFinal.Date.ToString("yyyy/MM/dd") + "'" +
                              " ORDER BY R.Fecha, R.ReservaID";

            //Construye sentencia de la primera banda, Reservas
            string strSql = "SELECT R.ReservaID, R.Fecha, T.Nombre as [Nombre Tercero],R.Referencia, R.Observacion, R.Estado " + 
                            " FROM RESERVA AS R " +
                            " INNER JOIN TERCERO T ON R.TerceroID = T.TerceroID " +
                            " WHERE " + tFiltro;
            DataTable dtReservas = new DataTable();
            accesoDatos p = new accesoDatos();
            dtReservas = p.leerDatosSQL(strSql, "");
            dtReservas.TableName = "Reservas";
            try
            {
                dsDatos.Tables.Add(dtReservas);
            }
            catch (DataException ex)
            {
                //Ya exsiste la tabla, se adicionan los registros
                foreach (DataRow fila in dtReservas.Rows)
                {
                    dsDatos.Tables["Reservas"].ImportRow(fila);
                }
            }
            //Construir sentencia para la segunda banda detalle de la reserva
            strSql = "SELECT D.ReservaID, D.ProductoID, P.Nombre, D.Reservado, D.Saldo, P.UnidadManejoID " +
                            " FROM RESERVA AS R " +
                            " INNER JOIN TERCERO T ON R.TerceroID = T.TerceroID " +
                            " INNER JOIN DETRES D ON R.ReservaID = D.ReservaID " +
                            " INNER JOIN PRODUCTO P ON D.ProductoID = P.ProductoID " +
                            " WHERE " + tFiltro;
            DataTable dtDetalle = new DataTable();
            dtDetalle = p.leerDatosSQL(strSql, "");
            dtDetalle.TableName = "DetRes";
            try
            {
                dsDatos.Tables.Add(dtDetalle);
                //Crear relacion entre las dos tablas
                DataRelation relResDetalle = new DataRelation("ResDetale"
                                            , dsDatos.Tables["Reservas"].Columns["ReservaID"]
                                            , dsDatos.Tables["DetRes"].Columns["ReservaID"]);
                dsDatos.Relations.Add(relResDetalle);
            }
            catch (DataException ex)
            {
                //Ya exsiste la tabla, se adicionan los registros
                foreach (DataRow fila in dtDetalle.Rows)
                {
                    dsDatos.Tables["DetRes"].ImportRow(fila);
                }
            }
        }
        public DataTable leerReservasConfirmadas()
        {
            //Llamado desde llenar listas de frmMoviInve
            string strSql = "SELECT R.ReservaID, R.Fecha,R.TerceroID, T.Nombre as [Nombre Tercero],R.Referencia,R.Observacion " +
                            " FROM RESERVA AS R " +
                            " INNER JOIN TERCERO T ON R.TerceroID = T.TerceroID " +
                            " INNER JOIN DETRES D ON R.ReservaID = D.ReservaID " +
                            " WHERE Estado = 'C'" +
                            " GROUP BY  R.ReservaID, R.Fecha, R.TerceroID, R.Referencia, T.Nombre, R.Observacion " +
                            " HAVING Sum(Saldo) > 0 " +
                            " ORDER BY R.Fecha, R.ReservaID";
            DataTable dt = new DataTable();
            accesoDatos p = new accesoDatos();
            dt = p.leerDatosSQL(strSql, "");
            return dt;
        }
        #endregion Metodos Publicos

        #region Metodos Privados
        private void asignarRegistro(DataSet dsDatos)
        {
            //Asignar los valores de la fila a las propiedades de la clase
            DataRow fila = dsDatos.Tables["Reserva"].Rows[0];
            ReservaID = fila["ReservaID"].ToString();
            Fecha = Convert.ToDateTime(fila["Fecha"]);
            Estado = Convert.ToChar(fila["Estado"]);
            TerceroID = Convert.ToInt32(fila["TerceroID"]);
            Referencia = fila["Referencia"].ToString();
            Observacion = fila["Observacion"].ToString();
        }
        private void actualizarRegistro(DataSet dsDatos)
        {
            //Instanciar el string SQL que se enviara a la Base de datos
            mSql.Clear();
            //Actualiza el registro de reserva
            mSql.Add("UPDATE RESERVA SET " +
                    " TerceroID = " + TerceroID +
                    ",Referencia = '" + Referencia + "'" +
                    ",Observacion = '" + Observacion + "'" +
                    ",UsuUltMod = '" + UsuUltMod + "'" +
                    ",FecUltMod = '" + FecUltMod.ToString("MM/dd/yyyy HH:mm:ss") + "' " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            //Borrar el detalle para volverlo a crear
            mSql.Add("DELETE FROM DETRES " +
                    " WHERE ReservaID = '" + ReservaID + "'");
            //Salvar el detalle de las reservas
            foreach (DataRow fila in dsDatos.Tables["DetRes"].Rows)
            {
                if (fila.RowState != DataRowState.Deleted)
                {
                    //Para cada registro en el detalle se debe crear una sentencia INSERT
                    mSql.Add(insertarFilaDetalle(fila));
                }
            }
        }
        private bool insertarRegistro(DataSet dsDatos)
        {
            mSql.Add("INSERT INTO Reserva " +
                "(ReservaID,TerceroID, Referencia,Estado, Fecha, Observacion," +
                "CodUsuCre,FecHorCre,UsuUltMod,FecUltMod) " +
                "VALUES ('" + ReservaID + "'" +
                ", '" + TerceroID + "','" + Referencia + "','" + Estado + "'" +
                ", '" + Fecha.ToString("MM/dd/yyyy") + "'" +
                ",'" + Observacion + "'" +
                ",'" + CodUsuCre + "'" +
                ",'" + FecHorCre.ToString("MM/dd/yyyy HH:mm:ss") + "'" +
                ",'" + UsuUltMod + "'" +
                ",'" + FecUltMod.ToString("MM/dd/yyyy HH:mm:ss") + "')");
            //Salvar el detalle de las reservas
            foreach (DataRow fila in dsDatos.Tables["DetRes"].Rows)
            {
                //Para cada registro en el detalle se debe crear una sentencia INSERT
                mSql.Add(insertarFilaDetalle(fila));
            }
            //Actualizar consecutivo reservas
            //mSql.Add(actualizarConsecReserva());
            return true;
        }
        private string insertarFilaDetalle(DataRow pFila)
        {
            string pCantidad = Utilidades.convertirComaPunto(Convert.ToDouble(pFila["Reservado"]));
            //Crear el string para insertar una fila en el detalle usando los valores por parametros
            return ("INSERT INTO DetRes " +
                    "(ReservaID, ProductoID, Reservado, Utilizado, Saldo) " +
                    "VALUES ('" + ReservaID + "'" + 
                    ",'" + pFila["ProductoID"].ToString() + "'" +
                    "," + pCantidad + ",0, 0)");
        }
        private int leerConsecReserva()
        {
            string tSql = "SELECT ConsReserva FROM EMPRESA WHERE EmpresaID = " + Usuario.EmpresaID;
            accesoDatos p = new accesoDatos();
            return int.Parse(p.leerValorSQL(tSql, ""));
        }
        private string actualizarConsecReserva()
        {
            return "UPDATE EMPRESA SET ConsReserva = " + ReservaID +
                   " WHERE EmpresaID = " + Usuario.EmpresaID;
        }
        #endregion Metodos Privados


    }
}
